/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.aries.samples.transaction;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.xa.XAResource;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.jdbc.DataSourceFactory;
public class TxDBServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String OSGI_BUNDLECONTEXT_ATTRIBUTE = "osgi-bundlecontext";
private static final String CLEAN_TABLE = "delete from txDemo";
private static final String SELECT_TABLE = "SELECT * FROM txDemo";
private static final String INSERT_INTO_TABLE = "INSERT INTO txDemo VALUES(?)";
private static final String LOGO_HEADER = "<TABLE border='0\' cellpadding=\'0\' cellspacing='0' width='100%'> " +
"<TR> " +
"<TD align='left' class='topbardiv' nowrap=''>" +
"<A href='http://incubator.apache.org/aries/' title='Apache Aries (incubating)'>" +
"<IMG border='0' src='http://incubator.apache.org/aries/images/Arieslogo_Horizontal.gif'>" +
"</A>" +
"</TD>" +
"<TD align='right' nowrap=''>" +
"<A href='http://www.apache.org/' title='The Apache Software Foundation'>" +
"<IMG border='0' src='http://incubator.apache.org/aries/images/apache-incubator-logo.png'>" +
"</A>"+
"</TD>"+
"</TR>"+
"</TABLE>";
private PrintWriter pw = null;
public void init() throws ServletException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
pw = response.getWriter();
pw.write(LOGO_HEADER);
// Get the bundle context from ServletContext attributes
BundleContext ctx = (BundleContext) getServletContext().getAttribute(OSGI_BUNDLECONTEXT_ATTRIBUTE);
pw.println("<html>");
pw.println("<head>");
pw.println("<link rel=\"stylesheet\" type=\"text/css\" href=\"tableTemplate.css\"/>");
pw.println("<body>");
pw.println("<h2 align=center><p><font face=\"Tahoma\">Sample Application for JDBC usage in JTA Transactions.</font></h2>");
pw.println("<p><p>");
ServiceReference tmServiceRef = ctx.getServiceReference("javax.transaction.TransactionManager");
ServiceReference derbyServiceRef = ctx.getServiceReference(DataSourceFactory.class.getName());
if(tmServiceRef == null || derbyServiceRef == null){
pw.println("<font face=\"Tahoma\">TransactionManager or Derby driver are not available in the OSGI registry.</font><br>");
} else {
TransactionManager tm = (TransactionManager)ctx.getService(tmServiceRef);
DataSourceFactory derbyRegistry = (DataSourceFactory)ctx.getService(derbyServiceRef);
try{
// Set the needed properties for the database connection
Properties props = new Properties();
props.put(DataSourceFactory.JDBC_URL, "jdbc:derby:txDemo");
props.put(DataSourceFactory.JDBC_DATABASE_NAME, "txDemo");
props.put(DataSourceFactory.JDBC_USER, "");
props.put(DataSourceFactory.JDBC_PASSWORD, "");
XADataSource xaDataSource = derbyRegistry.createXADataSource(props);
pw.println("<center><form><table><tr><td align='right'>Value: </td><td align=left><input type='text' name='value' value='' size='12'/><input type='submit' name='action' value='InsertAndCommit' size='100'/></td></tr>");
pw.println("<tr><td align='right'>Value: </td><td align=left><input type='text' name='value' value='' size='12'/><input type='submit' name='action' value='InsertAndRollback' size='100'/></center></td></tr>");
pw.println("<tr colspan='2' align='center'><td> </td><td><input type='submit' name='action' value='cleanTable' size='100' /> <input type='submit' name='action' value='printTable' size='100'/></td><tr></table></form></center>");
String value = request.getParameter("value");
String action = request.getParameter("action");
if(action != null && action.equals("InsertAndCommit")){
insertIntoTransaction(xaDataSource, tm, value, true);
} else if(action != null && action.equals("InsertAndRollback")){
insertIntoTransaction(xaDataSource, tm, value, false);
} else if(action != null && action.equals("cleanTable")){
cleanTable(xaDataSource);
}
printTable(xaDataSource);
} catch (Exception e){
pw.println("<font face=\"Tahoma\">Unexpected exception occurred "+ e.toString()+".</font><br>");
e.printStackTrace(pw);
}
}
pw.println("</body>");
pw.println("</html>");
pw.flush();
}// end of doGet(HttpServletRequest request, HttpServletResponse response)
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
doGet(request, response);
}// end of doPost(HttpServletRequest request, HttpServletResponse response)
/**
* Prints the table
* @param xaDataSource
* @throws SQLException
*/
private void printTable(XADataSource xaDataSource) throws SQLException {
XAConnection xaConnection = xaDataSource.getXAConnection();
Connection connection = xaConnection.getConnection();
PreparedStatement selectStatement = connection.prepareStatement(SELECT_TABLE);
ResultSet set = selectStatement.executeQuery();
pw.write("<center><br><table>");
pw.write("<tr BGCOLOR=#FFCC33>");
pw.write("<td><font face=\"Tahoma\"><b>VALUES</font></td>");
pw.write("</tr>");
while (set.next()) {
pw.write("<tr>");
pw.write("<td><font face=\"Tahoma\">");
pw.write(set.getString("value"));
pw.write("</font></td>");
pw.write("</tr>");
}
pw.write("</table><br></center>");
}
/**
* This method demonstrates how to enlist JDBC connection into Transaction according OSGi enterprise specification.
*
* @param xads XADataSource
* @param tm TransactionManager
* @param value which will be inserted into table
* @param toCommit Specify if the transaction will be committed or rolledback
* @throws SQLException
* @throws GenericJTAException
*/
private void insertIntoTransaction(XADataSource xads, TransactionManager tm, String value, boolean toCommit) throws SQLException, GenericJTAException{
XAConnection xaConnection = xads.getXAConnection();
Connection connection = xaConnection.getConnection();
XAResource xaResource = xaConnection.getXAResource();
try{
tm.begin();
Transaction transaction = tm.getTransaction();
transaction.enlistResource(xaResource);
PreparedStatement insertStatement = connection.prepareStatement(INSERT_INTO_TABLE);
insertStatement.setString(1, value);
insertStatement.executeUpdate();
if(toCommit){
transaction.commit();
} else {
transaction.rollback();
}
}catch(RollbackException e){
throw new GenericJTAException(e);
} catch (SecurityException e) {
throw new GenericJTAException(e);
} catch (IllegalStateException e) {
throw new GenericJTAException(e);
} catch (HeuristicMixedException e) {
throw new GenericJTAException(e);
} catch (HeuristicRollbackException e) {
throw new GenericJTAException(e);
} catch (SystemException e) {
throw new GenericJTAException(e);
} catch (NotSupportedException e) {
throw new GenericJTAException(e);
}
}
/**
* Cleans the Table
*
* @param xaDataSource
* @throws SQLException
*/
private void cleanTable(XADataSource xaDataSource) throws SQLException {
XAConnection xaConnection = xaDataSource.getXAConnection();
Connection connection = xaConnection.getConnection();
PreparedStatement statement = connection.prepareStatement(CLEAN_TABLE);
statement.executeUpdate();
}
}